package controllers;

import com.google.gson.Gson;
import models.ru.paralainer.chat.server.annotations.HttpBasic;
import models.ru.paralainer.chat.server.conf.PropertiesHolder;
import models.ru.paralainer.chat.server.dao.UserDAO;
import models.ru.paralainer.chat.server.domain.User;
import models.ru.paralainer.chat.server.dto.ErrorDTO;
import play.mvc.Before;
import play.mvc.Controller;
import play.mvc.Finally;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Collections;

/**
 * User: stalov
 * Date: 01.08.12
 * Time: 11:59
 */
public class BaseController extends Controller {

    public static final String INVALID_USERNAME = "Invalid username or password";

    @Before
    public static void checkHttpBasicAuth() {
        if (!isHttpBasic()) {
            return;
        }
        if (request.password == null || request.user == null) {
            unauthorized();
        }
        User user = fetchUser();
        if (!request.password.equals(user.getPassword())){
            renderJSON(new ErrorDTO(INVALID_USERNAME));
        }

    }

    public static boolean isHttpBasic() {
        return getActionAnnotation(HttpBasic.class) != null;
    }

    public static User fetchUser() {
        if (isHttpBasic()) {
            User user = UserDAO.INSTANCE.findByUsername(request.user);
            if (user == null) {
                if (PropertiesHolder.getAutoCreateUsers()) {
                    user = new User();
                    user.setPassword(request.password);
                    user.setUsername(request.user);
                    user.save();
                } else {
                    unauthorized();
                }
            }
            return user;

        }
        unauthorized();
        return null;
    }

    @Finally
    public static void deleteCookies(){
        if (isHttpBasic()){
            request.cookies = Collections.emptyMap();
        }
    }
    
    public static <T> T parseRequest(Class<T> clazz){
        Gson gson = new Gson();
        try {
            return gson.fromJson(inputStreamToString(request.body), clazz);
        }
        catch (IOException e) {
            renderJSON(new ErrorDTO("Can't parse request"));
            return null;
        }
    }

    private static String inputStreamToString(InputStream stream) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
        StringBuilder builder = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            builder.append(line);
            builder.append("\n");
        }
        return builder.toString();

    }

}
